﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EzDesk.Apps.Model.Attendance;
using NUnit.Framework;

namespace EzDesk.Apps.UnitTest
{
    [TestFixture]
    public class AttendanceServiceFixture
    {
        public AttendanceServiceContext PublicContext { get; set; }

        #region [ private methods ]
        private void assertAttendanceStatus(AttendanceStatus attendanceStatus, string dutyStr, bool isAbnormal, bool isDuplicated)
        {
            AttendanceType attendanceType;
            Enum.TryParse<AttendanceType>(dutyStr, out attendanceType);

            Assert.AreEqual(attendanceType, attendanceStatus.AttendanceType);
            Assert.AreEqual(isAbnormal, attendanceStatus.IsAbnormal);
            Assert.AreEqual(isDuplicated, attendanceStatus.IsDuplicated);
        }
        #endregion

        [SetUp]
        public void Setup()
        {
            this.PublicContext = new AttendanceServiceContext();
        }
        

        #region [ GetAttendanceStatus 测试方法 ]

        // 均为非长成考勤的GetAttendanceStatus
        [Test]
        public void Test_一天都是非正常考勤的情况()
        {
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-19");
            AttendanceStatus attendanceStatus;

            // 0:10 上下班都是非正常
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 0:10:00"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", true, false);
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 0:10:00"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);

            context.SetupAttendanceInfo("0:10:00", "onduty", true);

            // 1:10 上下班都是非正常
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 1:10:00"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);


            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 1:10:00"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", true, false);
        }



        [Test]
        public void Test_当日早上正常时间上班_上班正常无重复考勤()
        {
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-19");

            AttendanceStatus attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 9:10:00"), AttendanceType.onDuty
                ).Result;

            assertAttendanceStatus(attendanceStatus, "onduty", false, false);
        }

        [Test]
        public void Test_当日下午正常时间下班_早上正常上过班_下班正常无重复考勤()
        {
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-19")

                .SetupAttendanceInfo("8:50:00", "onduty", false);

            AttendanceStatus attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 18:10:00"), AttendanceType.offDuty
                ).Result;

            assertAttendanceStatus(attendanceStatus, "offDuty", false, false);
        }

        [Test]
        public void Test_凌晨下班_早上正常上班_下午正常下班()
        {
            AttendanceStatus attendanceStatus;

            var context = new  AttendanceServiceContext()
                .SetupDay("2010-11-19");
            
            // 凌晨下班，非正常考勤
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 02:02:24"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);
            context.SetupAttendanceInfo("02:24:22", "offduty", true);

            // 早上过来正常上班，正常考勤
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 08:50:24"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", false, false);
            context.SetupAttendanceInfo("08:50:24", "onDuty", false);

            // 下午下班，正常考勤
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 17:50:24"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", false, false);
        }

        [Test]
        public void Test_当日已正常上班_再正常上班_重复考勤()
        {
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-19")
                .SetupAttendanceInfo("09:02:00", "onDuty", false);

            AttendanceStatus attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 09:05:24"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", false, true);
        }

        [Test]
        public void Test_当日已正常上班正常下班_再正常下班_重复考勤()
        {
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-19")
                .SetupAttendanceInfo("09:02:00", "onDuty", false)
                .SetupAttendanceInfo("18:02:00", "offDuty", false);

            AttendanceStatus attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 18:05:00"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", false, true);
        }

        [Test]
        public void Test_周末随时上下班_都为非正常上班()
        {
            AttendanceStatus attendanceStatus;
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-20");

            // 凌晨上下班
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-20 02:02:24"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);

            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-20 02:02:24"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", true, false);

            // 上午上下班
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-20 09:02:24"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);

            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-20 09:02:24"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", true, false);

            // 下午上下班
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-20 17:02:24"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);

            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-20 17:02:24"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", true, false);
        }

        [Test]
        public void Test_上午请假两小时_上午非正常上班_下午非正常下班()
        {
            AttendanceStatus attendanceStatus;
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-19")

                .SetupLeaveInfo("外出", "8:00:00", "10:00:00", "2010-11-18 10:00:00", true, true, Guid.Empty, "2010-11-18 10:02:02");

            // 早上非正常上班
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 09:50:24"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", true, false);
            context.SetupAttendanceInfo("09:50:24", "onduty", true);

            // 下午非正常下班
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 17:50:24"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);
            context.SetupAttendanceInfo("17:50:24", "offduty", true);
        }

        [Test]
        public void Test_上午请假到下午_下午非正常上班_下午非正常下班()
        {
            AttendanceStatus attendanceStatus;
            var context = new AttendanceServiceContext()
                .SetupDay("2010-11-19")

                .SetupLeaveInfo("外出", "8:00:00", "14:00:00", "2010-11-18 10:00:00", true, true, Guid.Empty, "2010-11-18 10:02:02");

            // 早上非正常上班
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 13:50:24"), AttendanceType.onDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "onDuty", true, false);
            context.SetupAttendanceInfo("13:50:24", "onduty", true);

            // 下午非正常下班
            attendanceStatus = context.Service.GetAttendanceStatus(
                Guid.Empty, DateTime.Parse("2010-11-19 17:50:24"), AttendanceType.offDuty
                ).Result;
            assertAttendanceStatus(attendanceStatus, "offDuty", true, false);
            context.SetupAttendanceInfo("17:50:24", "offduty", true);
        }

        #endregion

        #region [ GetAttendanceInfoList 测试方法 ]
        [Test]
        public void Test_获得当日所有考勤信息()
        {
            var context = new AttendanceServiceContext()
            .SetupDay("2010-11-19")
            .SetupAttendanceInfo("08:50:00", "onduty", false)
            .SetupAttendanceInfo("18:50:00", "onduty", false)
            .SetupAttendanceInfo("08:50:11", "onduty", true)

            .SetupDay("2010-11-20")
            .SetupAttendanceInfo("08:50:00", "onduty", false);

            var testDay = DateTime.Parse("2010-11-19");
            var list = context.Service.GetAttendanceInfoListByUsersInDay(
                testDay,
                null,
                null
                ).Result;

            Assert.AreEqual(list.Where(p=>p.Date.Date != testDay).Count(), 0);

        }
        #endregion

    }
}
